package com.sd365.permission.centre.service.impl;/*
角色服务
@author wang hon
@date 2022/12/16 14：13
**/

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.DataBaseException;
import com.sd365.common.core.common.exception.code.BusinessErrorCode;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanUtil;
import com.sd365.common.util.DateUtil;
import com.sd365.permission.centre.dao.mapper.*;
import com.sd365.permission.centre.entity.*;
import com.sd365.permission.centre.pojo.dto.*;
import com.sd365.permission.centre.pojo.query.RoleQuery;
import com.sd365.permission.centre.pojo.query.UserQuery;
import com.sd365.permission.centre.pojo.vo.*;
import com.sd365.permission.centre.service.RoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

@Slf4j
@Service
public class RoleServiceImpl extends AbstractBaseDataServiceImpl implements RoleService {
    @javax.annotation.Resource
    RoleMapper roleMapper;
   @javax.annotation.Resource
    RoleResourceMapper roleResourceMapper;
   @Autowired
   RedisTemplate redisTemplate;
   @Autowired
    DataSourceTransactionManager dataSourceTransactionManager;
   @javax.annotation.Resource
    UserRoleMapper userRoleMapper;
   @javax.annotation.Resource
    UserMapper userMapper;
   @javax.annotation.Resource
   CompanyMapper companyMapper;
   @javax.annotation.Resource
   RoleCompanyMapper roleCompanyMapper;
    @Autowired
    private IdGenerator idGenerator;
    @Resource
    ResourceMapper resourceMapper;
    @Resource
    UserServiceImpl userService;
    @Resource
    TenantMapper tenantMapper;
    @Override
    public Boolean initRoleResourceRedis(Role role) {
        /*判断是否有该角色如果有则删除关系*/
        if(roleMapper.haveRole(role)>0){
             roleResourceMapper.deleteByRoleId(role.getId());
             return  true;
        } else {
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = DataBaseException.class)
    public Boolean assignResource(RoleResourceDTO roleResourceDTO) {
        if(roleResourceDTO==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        }
        List<Long> list=roleResourceDTO.getRoleIds();
        RoleResource roleResource =BeanUtil.copy(roleResourceDTO,RoleResource.class);
        List<Long> resourceIds =roleResourceDTO.getResourceIds();
        if(list!=null) {
               for(Long l:list){
                  if(roleMapper.selectById(l)!=null){
                      roleResourceMapper.deleteByRoleId(l);
                      for(Long resourceId: resourceIds){
                          if(resourceId==null){
                              continue;
                          }
                      roleResource.setId(idGenerator.snowflakeId());
                      Date data=DateUtil.getCurrentDate();
                      roleResource.setRoleId(l);
                      roleResource.setResourceId(resourceId);
                      roleResource.setUpdatedTime(data);
                      Company company=BeanUtil.copy(roleResourceDTO.getCompanyDTO(), Company.class);
                      roleResource.setCompany(company);
                      roleResource.setVersion(1l);
                      roleResource.setStatus((byte) 1);
                      roleResource.setCreatedTime(DateUtil.getCurrentDate());
                      if(roleResource.getCreatedBy()==null){roleResource.setCreatedBy(1337970508645400576l);}
                      roleResource.setTenant(BeanUtil.copy(roleResourceDTO.getTenantDTO(), Tenant.class));
                      roleResource.setOrganization(BeanUtil.copy(roleResourceDTO.getOrganizationDTO(),Organization.class));
                      if(roleResourceMapper.insertRoleResource(roleResource)>0){
                         }else {
                          throw  new DataBaseException();
                      }
                  }}else {
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("没有对应的角色或资源"));
            }
               }
                    return  true;
        }else {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("角色为空"));
        }
    }

    @Override
    @Transactional(rollbackFor = DataBaseException.class)
    public Boolean assignUser(UserRoleDTO userRoleDTO) {
        if(userRoleDTO==null||userRoleDTO.getRoleIds()==null||userRoleDTO.getUserIds()==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        }
        List<Long> roleIds = userRoleDTO.getRoleIds();
        List<Long> userIds = userRoleDTO.getUserIds();
        UserRole userRole=BeanUtil.copy(userRoleDTO,UserRole.class);
            for (Long f : roleIds) {
                Example example=new Example(UserRole.class);
                example.createCriteria().andEqualTo("roleId",f);
                if(roleMapper.selectById(f)==null){
                    throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("没有ID为："+f+"的角色"));
                }
                if (!userRoleMapper.selectByExample(example).isEmpty()&&userRoleMapper.selectByExample(example)!=null){
                if(userRoleMapper.deleteByExample(example)<=0){
                    throw new DataBaseException();
                }
                }
                for (Long v:userIds){
                    if(userMapper.selectById(v)==null){
                        throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("没有该用户"));
                    }
                    userRole.setRoleId(f);
                    userRole.setUserId(v);
                    userRole.setId(idGenerator.snowflakeId());
                    userRole.setCreatedTime(DateUtil.getCurrentDate());
                    if(userRoleDTO.getCreatedBy()==null){
                    userRole.setCreatedBy(1337970508645400576l);}
                    userRole.setStatus((byte) 1);
                    userRole.setVersion(1l);
                    userRole.setUpdatedTime(DateUtil.getCurrentDate());
                    if(userRoleMapper.insert(userRole)<=0)
                    {
                        throw new DataBaseException();
                           }
                }
            }
            return true;

    }
    @Override
    public List<Node> queryResourceByRoleId(long roleId) {
        if(roleMapper.selectById(roleId)==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        }
        return roleResourceMapper.queryResourceByRoleId(roleId);
    }

    @Override
    public List<Node> selectCompany() {
        return roleMapper.selectCompany();
    }

    @Override
    public boolean haveRole(RoleDTO roleDTO) {
        if(roleDTO==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        }
        List<Role> roles=roleMapper.selectAll();
        int i=0;
        int j=0;
        for (Role role:roles){
            if(!role.getCode().equals(roleDTO.getCode())){
             i++;
            }
            if(!role.getId().equals(roleDTO.getId())){
                j++;
            }
        }
        if(i==roles.size()||j==roles.size()){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误:角色信息不存在"));
        }
        Role role=BeanUtil.copy(roleDTO,Role.class);
        if(roleMapper.haveRole(role)>0){
            return true;
        }else {return false;}
    }
    @Transactional
    @Override
    public Boolean add(RoleDTO roleDTO) {
             List<Role> roles=roleMapper.selectAll();
             if(roleMapper.selectById(roleDTO.getId())==null){
             for (Role role:roles){
                if(role.getCode().equals(roleDTO.getCode())){
                     throw new BusinessException( BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("code重复"));
                }
             }}
            if (roleDTO != null&&roleDTO.getResourceDTOS()!=null&&roleDTO.getCompanyDTO()!=null){
                Role role1 = BeanUtil.copy(roleDTO, Role.class);
                if (role1.getCreatedBy()==null){
                role1.setCreatedBy(1337970508645400576l);
                }
                role1.setId(idGenerator.snowflakeId());
                role1.setUpdatedTime(DateUtil.getCurrentDate());
                role1.setCreatedTime(DateUtil.getCurrentDate());
                role1.setOrganization(BeanUtil.copy(roleDTO.getOrganizationDTO(),Organization.class));
                role1.setTenant(BeanUtil.copy(roleDTO.getTenantDTO(),Tenant.class));
                role1.setStatus((byte) 1);
                RoleResource roleResource=new RoleResource();
                Company company1=BeanUtil.copy(roleDTO.getCompanyDTO(), Company.class);
                role1.setCompany(company1);
                if(roleMapper.insert(role1)<0){
                    throw new DataBaseException();
                }
                List<ResourceDTO> resourceDTOS = roleDTO.getResourceDTOS();
                if(!resourceDTOS.isEmpty()&&resourceDTOS.size()>1){
                    for (ResourceDTO s : resourceDTOS) {
                        Date date=DateUtil.getCurrentDate();
                        roleResource.setUpdatedTime(date);
                        roleResource.setRoleId(role1.getId());
                        roleResource.setResourceId(s.getId());
                        roleResource.setCreatedTime(date);
                        roleResource.setOrganization(role1.getOrganization());
                        roleResource.setTenant(role1.getTenant());
                        roleResource.setId(idGenerator.snowflakeId());
                        roleResource.setCompany(company1);
                        roleResource.setCreatedBy(role1.getCreatedBy());
                        roleResource.setUpdatedBy(role1.getUpdatedBy());
                        roleResource.setVersion(role1.getVersion());
                        roleResource.setTenantId(role1.getTenantId());
                        roleResource.setOrgId(role1.getOrgId());
                        roleResource.setCompanyId(role1.getCompanyId());
                        if (roleResourceMapper.insertRoleResource(roleResource)<0) {
                            throw  new DataBaseException();
                        }
                    }
                }}else {
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
            }
            return true;
    }

    @Override
    @Transactional(rollbackFor = DataBaseException.class)
    public Boolean remove(Long id, Long version) {
        if(roleMapper.selectById(id)!=null&&version!=null){
            Example example=new Example(Role.class);
            example.createCriteria().andEqualTo("id",id).andEqualTo("version",version);
            Example example1=new Example(UserRole.class);
            example1.createCriteria().andEqualTo("roleId",id);
            Example example2=new Example(RoleResource.class);
            example.createCriteria().andEqualTo("id",id);
            if (!roleResourceMapper.selectByExample(example2).isEmpty()) {
                if( roleResourceMapper.deleteByExample(example2)<0){
                    throw new DataBaseException();
                }}
            if(!userRoleMapper.selectByExample(example1).isEmpty()){
                if(userRoleMapper.deleteByExample(example1)<0){
                    throw new DataBaseException();
                }
            }
            if(roleMapper.deleteByExample(example)<0){
                throw  new DataBaseException();
            }
            return true;
        } else throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
    }

    @Override
    public RoleDTO modify(RoleDTO roleDTO) {
        if(roleDTO==null||roleDTO.getCompanyId()==null||roleDTO.getOrgId()==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        }
        if(roleMapper.selectById(roleDTO.getId())==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("没有该角色"));
        }
        Role role2=roleMapper.selectById(roleDTO.getId());
        if (!role2.getCode().equals(roleDTO.getCode())){
        List<Role> roles=roleMapper.selectAll();
        for (Role role:roles){
            if(role.getCode().equals(roleDTO.getCode())){
                throw new BusinessException( BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("code重复"));
            }
        }}
         Role role1=BeanUtil.copy(roleDTO,Role.class);
         super.baseDataStuff4Updated(role1);
         role1.setUpdatedTime(DateUtil.getCurrentDate());
         if(roleDTO.getUpdatedBy()==null){
             role1.setUpdatedBy(1337970508645400576l);
         }
        Example example=new Example(Role.class);
         example.createCriteria().andEqualTo("id",roleDTO.getId());
        if(roleMapper.updateByExample(role1,example)>0){
            return roleDTO;
        }else {
            throw  new DataBaseException();
        }

    }

    @Override
    public List<RoleDTO> commonQuery(RoleQuery roleQuery) {
        if (roleQuery == null) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("commonQuery 方法错误"));
        }
        List<Role> roles;
        PageHelper.startPage(roleQuery.getPageNum(),roleQuery.getPageSize());
            Role role=BeanUtil.copy(roleQuery,Role.class);
            roles=roleMapper.commonQuery(role);
            if (roles!=null){
            Page page= (Page) roles;
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
            DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return BeanUtil.copyList(roles, RoleDTO.class, new BeanUtil.CopyCallback() {
           @Override
           public void copy(Object o, Object o1) {
               Role role1 = (Role) o;
               RoleDTO roleDTO = (RoleDTO) o1;
               if (role1.getOrganization()!= null) {
                   OrganizationDTO copy = BeanUtil.copy(role1.getOrganization(), OrganizationDTO.class);
                   roleDTO.setOrganizationDTO(copy);
               }
               if (role1.getCompany()!= null) {
                  CompanyDTO companyDTO= BeanUtil.copy(role1.getCompany(), CompanyDTO.class);
                  roleDTO.setCompanyDTO(companyDTO);
               }
               if(role1.getTenant()!=null){
                   TenantDTO tenantDTO=BeanUtil.copy(role1.getTenant(),TenantDTO.class);
                   roleDTO.setTenantDTO(tenantDTO);
               }

           }
       });
        }else {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("没有角色"));
        }

    }

    @Override
    public RoleDTO queryById(Long id) {
        Role role1=roleMapper.selectById(id);
        if(role1==null){
            return  new RoleDTO();
        }else {
            RoleDTO roleDTO=BeanUtil.copy(role1,RoleDTO.class);
            OrganizationDTO organizationDTO=BeanUtil.copy(role1.getOrganization(),OrganizationDTO.class);
            roleDTO.setOrganizationDTO(organizationDTO);
            CompanyDTO companyDTO=BeanUtil.copy(role1.getCompany(), CompanyDTO.class);
            roleDTO.setCompanyDTO(companyDTO);
            TenantDTO tenantDTO=BeanUtil.copy(role1.getTenant(),TenantDTO.class);
            roleDTO.setTenantDTO(tenantDTO);
            List<Node> list=roleResourceMapper.queryResourceByRoleId(id);
            return roleDTO;
        }
    }

    @Override
    public RoleDTO copy(Long id) {
        if(roleMapper.selectById(id)==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        } else {
            Role role=new Role();
            role=roleMapper.selectById(id);
             if(roleMapper.insert(role)<=0){
                 throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("复制错误"));
             }
            RoleDTO roleDTO=BeanUtil.copy(role,RoleDTO.class);
             roleDTO.setUpdatedTime(role.getUpdatedTime());
            OrganizationDTO organizationDTO=BeanUtil.copy(role.getOrganization(),OrganizationDTO.class);
            roleDTO.setOrganizationDTO(organizationDTO);
            CompanyDTO companyDTO=BeanUtil.copy(role.getCompany(), CompanyDTO.class);
            roleDTO.setCompanyDTO(companyDTO);
            TenantDTO tenantDTO=BeanUtil.copy(role.getTenant(),TenantDTO.class);
            roleDTO.setTenantDTO(tenantDTO);
            return roleDTO;
        }

    }
    @Transactional(rollbackFor = DataBaseException.class)
    @Override
    public Boolean batchRemove(RoleDTO[] roleDTOS) {
        if (roleDTOS.length == 0||roleDTOS==null) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID, new Exception("方法错误"));
        }
        for (RoleDTO roleDTO: roleDTOS) {
            if(roleDTO.getId()==null){
                throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("roleId为空"));
            }
            Example example = new Example(Role.class);
            example.createCriteria().andEqualTo("id",roleDTO.getId()).andEqualTo("version",roleDTO.getVersion());
            Example example1=new Example(UserRole.class);
            example1.createCriteria().andEqualTo("roleId",roleDTO.getId());
            Example example2=new Example(RoleResource.class);
            example2.createCriteria().andEqualTo("roleId",roleDTO.getId());
            if (!roleResourceMapper.selectByExample(example2).isEmpty()) {
               if( roleResourceMapper.deleteByExample(example2)<0){
                   throw new DataBaseException();
               }}
                if(!userRoleMapper.selectByExample(example1).isEmpty()){
                   if(userRoleMapper.deleteByExample(example1)<0){
                       throw new DataBaseException();
                   }
                }
                if(roleMapper.deleteByExample(example)<0){
                    throw  new DataBaseException();
                }
        }
        return true;
    }

    @Override
    public List<UserDTO> commonQueryUser(UserQuery userQuery) {
           List<User> users=userService.commonQuery(userQuery);
           List<UserDTO> userDTOS=BeanUtil.copyList(users, UserDTO.class, new BeanUtil.CopyCallback() {
               @Override
               public void copy(Object o, Object o1) {
                   User user=(User) o;
                   UserDTO userDTO=(UserDTO) o1;
                   if(user.getRoleList()!=null){
                       userDTO.setRoleList(BeanUtil.copyList(user.getRoleList(),RoleDTO.class));
                   }
                   if(user.getOrganization()!=null){
                       userDTO.setOrganization(BeanUtil.copy(user.getOrganization(),OrganizationDTO.class));

                   }
                   if(user.getDepartment()!=null){
                       userDTO.setDepartment(BeanUtil.copy(user.getDepartment(),DepartmentDTO.class));
                   }
                   if(user.getCompany()!=null){
                       userDTO.setCompany(BeanUtil.copy(user.getCompany(),CompanyDTO.class));
                   }
               }
           });
           for (UserDTO user:userDTOS) {
               Tenant tenant = tenantMapper.selectById(user.getTenantId());
               user.setTenant(BeanUtil.copy(tenant,TenantDTO.class));
           }
          return userDTOS;
       }

    @Override
    public RoleDTO queryUserResource(Long id) {
        if(roleMapper.selectById(id)==null){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));}
        Role role=roleMapper.selectById(id);
        RoleDTO roleDTO=BeanUtil.copy(role,RoleDTO.class);
        OrganizationDTO organizationDTO=BeanUtil.copy(role.getOrganization(),OrganizationDTO.class);
        roleDTO.setOrganizationDTO(organizationDTO);
        CompanyDTO companyDTO=BeanUtil.copy(role.getCompany(), CompanyDTO.class);
        roleDTO.setCompanyDTO(companyDTO);
        TenantDTO tenantDTO=BeanUtil.copy(role.getTenant(),TenantDTO.class);
        roleDTO.setTenantDTO(tenantDTO);
        Example example1=new Example(RoleResource.class);
        example1.createCriteria().andEqualTo("roleId",id);
        List<RoleResource> resources=roleResourceMapper.selectByExample(example1);
        List<com.sd365.permission.centre.entity.Resource> resourceList = null;
         for (RoleResource roleResource:resources){
         com.sd365.permission.centre.entity.Resource resource= resourceMapper.findById(roleResource.getResourceId());
            if(resource!=null){
                resourceList.add(resource);
            }
        }
         List<ResourceDTO> resourceDTOS=BeanUtil.copyList(resourceList,ResourceDTO.class);
         roleDTO.setResourceDTOS(resourceDTOS);
        return roleDTO;
    }

    @Override
    public RoleCompanyVO queryRoleCompanyById(Long id) {
       Role role= roleMapper.selectById(id);
       if(role!=null) {
           List<Company> companies = companyMapper.findAllByOrgId(role.getOrgId());
           List<Long> authCompanyIds = new ArrayList<>();
               Example example = new Example(RoleCompany.class);
               example.createCriteria().andEqualTo("roleId",id);
               List<RoleCompany> roleCompanyList=roleCompanyMapper.selectByExample(example);
               for (RoleCompany roleCompany:roleCompanyList){
                   authCompanyIds.add(roleCompany.getAuthCompanyId());
               }
           RoleCompanyVO roleCompanyVO=new RoleCompanyVO();
               roleCompanyVO.setAuthCompanyIds(authCompanyIds);
               roleCompanyVO.setRoleId(id);
               return  roleCompanyVO;
       }
       else return null;
    }

    @Override
    public Boolean modifyRoleCompany(RoleCompanyDTO roleCompanyDTO) {
           if(roleCompanyDTO==null){
               throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
           }
           List<Long> roles=roleCompanyDTO.getRoleIds();
        List<Long>  authCompanyId=roleCompanyDTO.getAuthCompanyIds();
        RoleCompany roleCompany=BeanUtil.copy(roleCompanyDTO,RoleCompany.class);
        if(roles.size()<1){
            throw new BusinessException(BusinessErrorCode.SYSTEM_SERVICE_ARGUMENT_NOT_VALID,new Exception("参数错误"));
        }
        for (Long role:roles){
            if(role==null){
                continue;
            }
            roleCompany.setRoleId(role);
           for (Long a:authCompanyId){
               roleCompany.setAuthCompanyId(a);
               Example example = new Example(RoleCompany.class);
               example.createCriteria().andEqualTo("roleId",role);
               if (roleCompanyMapper.selectByExample(example).isEmpty()){
                   roleCompany.setId(idGenerator.snowflakeId());
                   if(roleCompanyDTO.getCreatedBy()==null){
                       roleCompany.setCreatedBy(1337970508645400576l);
                   }
                   roleCompany.setCreatedTime(DateUtil.getCurrentDate());
                     if(roleCompanyMapper.insert(roleCompany)<0){
                         throw new DataBaseException();
                     }
               }else {
                   roleCompany.setUpdatedBy(1337970508645400576l);
                   roleCompany.setUpdatedTime(DateUtil.getCurrentDate());
               if (roleCompanyMapper.updateByExample(roleCompany,example)<0){
                   throw new DataBaseException();
               }}
           }
        } return  true;
    }
}
